package com.atguigu.gulimall.product.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.atguigu.common.constant.ProductConstant;
import com.atguigu.common.to.SkuHasStockVo;
import com.atguigu.common.to.SkuReductionTo;
import com.atguigu.common.to.SpuBoundTo;
import com.atguigu.common.to.es.SkuEsModel;
import com.atguigu.common.utils.R;
import com.atguigu.gulimall.product.entity.*;
import com.atguigu.gulimall.product.feign.CouponFeignService;
import com.atguigu.gulimall.product.feign.MemberFeignService;
import com.atguigu.gulimall.product.feign.SearchFeignService;
import com.atguigu.gulimall.product.feign.WareFeignService;
import com.atguigu.gulimall.product.service.*;
import com.atguigu.gulimall.product.vo.*;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.atguigu.gulimall.product.dao.SpuInfoDao;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;
import org.springframework.transaction.annotation.Transactional;

@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    @Autowired
    SpuInfoDescService spuInfoDescService;

    @Autowired
    SpuImagesService spuImagesService;

    @Autowired
    AttrService attrService;

    @Autowired
    ProductAttrValueService productAttrValueService;

    @Autowired
    SkuInfoService skuInfoService;

    @Autowired
    SkuImagesService skuImagesService;

    @Autowired
    SkuSaleAttrValueService skuSaleAttrValueService;

    @Autowired
    CouponFeignService couponFeignService;

    @Autowired
    BrandService brandService;

    @Autowired
    CategoryService categoryService;

    @Autowired
    WareFeignService wareFeignService;

    @Autowired
    SearchFeignService searchFeignService;


    @Override
    public PageUtils queryPageByCondition(Map<String, Object> params) {
        QueryWrapper<SpuInfoEntity> queryWrapper = new QueryWrapper<>();
        String key = (String) params.get("key");
        if(!StringUtils.isEmpty(key)){
            queryWrapper.and(wrapper -> {
                wrapper.eq("id",key).or().like("spu_name",key);
            });
        }
        String status = (String) params.get("status");
        if(!StringUtils.isEmpty(status)){
            queryWrapper.eq("publish_status",status);
        }
        String brandId = (String) params.get("brandId");
        if(!StringUtils.isEmpty(brandId) && !"0".equalsIgnoreCase(brandId)){
            queryWrapper.eq("brand_id",brandId);
        }
        String catelogId = (String) params.get("catelogId");
        if(!StringUtils.isEmpty(catelogId)&& !"0".equalsIgnoreCase(catelogId)){
            queryWrapper.eq("catalog_id",catelogId);
        }
        IPage<SpuInfoEntity> page = this.page(
        new Query<SpuInfoEntity>().getPage(params), queryWrapper
        );

        return new PageUtils(page);
    }

    @Override
    @Transactional
    public void up(Long spuId) {
        List<SkuInfoEntity> skuInfoEntities=skuInfoService.getSkusBySpuId(spuId);
        List<Long> ids = skuInfoEntities.stream().map(SkuInfoEntity::getSkuId).collect(Collectors.toList());
        Map<Long, Boolean> map=null;
        try {
            R r = wareFeignService.getSkuHasStock(ids);
//            受保护的（protected）构造函数只能在以下几种情况下被访问:1、同一个包中的类 2、子类
//            匿名子类实际上是一个新的类，它继承了 TypeReference
            TypeReference<List<SkuHasStockVo>> typeReference=new TypeReference<List<SkuHasStockVo>>(){};
            List<SkuHasStockVo> skuHasStockVos = r.getData(typeReference);
            map = skuHasStockVos.stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, SkuHasStockVo::getHasStock));
        } catch (Exception e) {
            e.printStackTrace();
        }

//        1、通过spuId查询productAttrValueEntity中spuId的可被检索的属性，封装成SkuEsModel.Attrs
        List<ProductAttrValueEntity> productAttrValueEntities = productAttrValueService.list(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId));
        List<Long> spuAttrIdCollect = productAttrValueEntities.stream().map((item) -> {
            return item.getAttrId();
        }).collect(Collectors.toList());
        List<Long> attrIdCollect = spuAttrIdCollect.stream().map((item) -> {
            return attrService.getById(item);
        }).filter((item) -> {
            return item.getSearchType() == 1;
        }).map((item) -> {
            return item.getAttrId();
        }).collect(Collectors.toList());
        Set<Long> longSet=new HashSet<>(attrIdCollect);
//        有问题
//        List<SkuEsModel.Attrs> attrs = spuAttrIdCollect.stream().map((item) -> {
//            ProductAttrValueEntity productAttrValueEntity = productAttrValueService.getOne(new QueryWrapper<ProductAttrValueEntity>().in("attr_id", longSet).eq("spu_id", spuId));
//            SkuEsModel.Attrs attr = new SkuEsModel.Attrs();
//            BeanUtils.copyProperties(productAttrValueEntity,attr);
//            return attr;
//        }).collect(Collectors.toList());
        List<SkuEsModel.Attrs> attrs = productAttrValueEntities.stream().filter((item) -> {
            return longSet.contains(item.getAttrId());
        }).map((item) -> {
            SkuEsModel.Attrs attr = new SkuEsModel.Attrs();
            BeanUtils.copyProperties(item, attr);
            return attr;
        }).collect(Collectors.toList());
//        2、查出SkuEsModel中需要的sku的信息。
        Map<Long, Boolean> finalMap = map;
        List<SkuEsModel> skuEsModels = skuInfoEntities.stream().map(sku -> {
            SkuEsModel skuEsModel = new SkuEsModel();
            BeanUtils.copyProperties(sku, skuEsModel);
            skuEsModel.setSkuPrice(sku.getPrice());
            skuEsModel.setSkuImg(sku.getSkuDefaultImg());
            skuEsModel.setHotScore(0L);
            BrandEntity brandEntity = brandService.getById(sku.getBrandId());
            skuEsModel.setBrandName(brandEntity.getName());
            skuEsModel.setBrandImg(brandEntity.getLogo());
            CategoryEntity categoryEntity = categoryService.getById(sku.getCatalogId());
            skuEsModel.setCatalogName(categoryEntity.getName());
//            3、设置attrs
            skuEsModel.setAttrs(attrs);
//            4、设置hasStock
            skuEsModel.setHasStock(finalMap ==null?true: finalMap.get(sku.getSkuId()));
            return skuEsModel;
        }).collect(Collectors.toList());

//        TODO 上架商品
        R r = searchFeignService.productStatusUp(skuEsModels);
        if(r.getCode() == 0){
//            更新数据库
            this.update(new UpdateWrapper<SpuInfoEntity>().eq("id",spuId).set("publish_status", ProductConstant.ProductStatusEnum.SPU_UP.getCode()).set("update_time",new Date()));
        }else {
//            TODO
        }

    }

    @Override
    @Transactional
    public void saveSupInfo(SpuSaveVo spuSaveVo) {
        //1、保存spu基本信息：pms_spu_info，spuInfoEntity
        SpuInfoEntity spuInfoEntity=new SpuInfoEntity();
        BeanUtils.copyProperties(spuSaveVo,spuInfoEntity);
        spuInfoEntity.setCreateTime(new Date());
        spuInfoEntity.setUpdateTime(new Date());
        this.save(spuInfoEntity);
        Long spuId = spuInfoEntity.getId();
        //2、保存spu的描述图片：pms_spu_info_desc，SpuInfoDescEntity
        SpuInfoDescEntity spuInfoDescEntity=new SpuInfoDescEntity();
        spuInfoDescEntity.setSpuId(spuId);
        spuInfoDescEntity.setDecript(String.join(",",spuSaveVo.getDecript()));
        spuInfoDescService.save(spuInfoDescEntity);
        //3、保存spu的图片集：pms_spu_images,SkuImagesEntity
        spuImagesService.saveSpuImages(spuId,spuSaveVo.getImages());
        //4、保存spu的规格参数：pms_product_attr_value,ProductAttrValueEntity
        List<BaseAttrs> baseAttrs = spuSaveVo.getBaseAttrs();
        List<ProductAttrValueEntity> productAttrValueEntities = baseAttrs.stream().map((item) -> {
            ProductAttrValueEntity productAttrValueEntity = new ProductAttrValueEntity();
            productAttrValueEntity.setSpuId(spuId);
            productAttrValueEntity.setAttrId(item.getAttrId());
            AttrEntity attrEntity = attrService.getById(item.getAttrId());
            productAttrValueEntity.setAttrName(attrEntity.getAttrName());
            productAttrValueEntity.setAttrValue(item.getAttrValues());
            productAttrValueEntity.setQuickShow(item.getShowDesc());
            return productAttrValueEntity;
        }).collect(Collectors.toList());
        productAttrValueService.saveBatch(productAttrValueEntities);
        //5、保存spu的积分信息：gulimall_sms--->sms_spu_bounds，SpuBoundsEntity
        Bounds bounds = spuSaveVo.getBounds();
        SpuBoundTo spuBoundTo = new SpuBoundTo();
        BeanUtils.copyProperties(bounds, spuBoundTo);
        spuBoundTo.setSpuId(spuId);
        R r = couponFeignService.saveSpuBounds(spuBoundTo);

        if (r.getCode() != 0) {
            log.error("远程保存spu积分信息失败");
        }
        //6、保存当前spu对应的所有sku信息：pms_sku_info
        //6、1）、sku的基本信息:pms_sku_info,SkuInfoEntity
        List<Skus> skus = spuSaveVo.getSkus();
        for (Skus sku : skus) {
            String defaultImage = "";
            for (Images image : sku.getImages()) {
                if (image.getDefaultImg() == 1) {
                    defaultImage = image.getImgUrl();
                }
            }
            SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
            BeanUtils.copyProperties(sku, skuInfoEntity);
            skuInfoEntity.setSpuId(spuId);
            skuInfoEntity.setBrandId(spuInfoEntity.getBrandId());
            skuInfoEntity.setCatalogId(spuInfoEntity.getCatalogId());
            skuInfoEntity.setSaleCount(0L);
            skuInfoEntity.setSkuDefaultImg(defaultImage);
            skuInfoService.save(skuInfoEntity);
            Long skuId = skuInfoEntity.getSkuId();
            //6、2）、sku的图片信息：pms_sku_images
            List<SkuImagesEntity> skuImagesEntities = sku.getImages().stream().map((image -> {
                SkuImagesEntity skuImagesEntity = new SkuImagesEntity();
                BeanUtils.copyProperties(image, skuImagesEntity);
                skuImagesEntity.setSkuId(skuId);
                skuImagesEntity.setImgSort(0);
                return skuImagesEntity;
            })).filter((item)->{
                //返回true就是需要，false就是剔除
                return !StringUtils.isEmpty(item.getImgUrl());
            }).collect(Collectors.toList());
            skuImagesService.saveBatch(skuImagesEntities);
            //6、3）、sku的销售属性：pms_sku_sale_attr_value,SkuSaleAttrValueEntity
            List<Attr> attr = sku.getAttr();
            List<SkuSaleAttrValueEntity> skuSaleAttrValueEntities = attr.stream().map((item) -> {
                SkuSaleAttrValueEntity skuSaleAttrValueEntity = new SkuSaleAttrValueEntity();
                BeanUtils.copyProperties(item, skuSaleAttrValueEntity);
                skuSaleAttrValueEntity.setSkuId(skuId);
                skuSaleAttrValueEntity.setAttrSort(0);
                return skuSaleAttrValueEntity;
            }).collect(Collectors.toList());
            skuSaleAttrValueService.saveBatch(skuSaleAttrValueEntities);
            //6、4）、sku的优惠、满减等信息：gulimall_sms--->sms_sku_ladder、sms_sku_full_reduction、sms_member_price
            SkuReductionTo skuReductionTo = new SkuReductionTo();
            BeanUtils.copyProperties(sku,skuReductionTo);
            skuReductionTo.setSkuId(skuId);
            if (skuReductionTo.getFullCount() > 0 || skuReductionTo.getFullPrice().compareTo(BigDecimal.ZERO) == 1) {
                R r1 = couponFeignService.saveSkuReduction(skuReductionTo);
                if (r1.getCode() != 0) {
                    log.error("远程保存sku积分信息失败");
                }
            }
        }

    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                new QueryWrapper<SpuInfoEntity>()
        );

        return new PageUtils(page);
    }

}